import subprocess
import time
import random
import os
import argparse
import sys
import datetime
import re

# 获取脚本所在目录
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
# 获取父目录（QtScrcpy根目录）
ROOT_DIR = os.path.dirname(SCRIPT_DIR)
# adb和scrcpy可执行文件路径
ADB_PATH = os.path.join(ROOT_DIR, "adb.exe")
SCRCPY_PATH = os.path.join(ROOT_DIR, "scrcpy.exe")

def check_adb_device():
    """检查是否有ADB设备连接"""
    result = subprocess.run([ADB_PATH, "devices"], capture_output=True, text=True)
    # 跳过第一行(标题)并检查是否有设备列出
    devices = result.stdout.strip().split('\n')[1:]
    return len([d for d in devices if d.strip()]) > 0

def get_device_resolution():
    """获取设备屏幕分辨率"""
    try:
        result = subprocess.run(
            [ADB_PATH, "shell", "wm", "size"], 
            capture_output=True, 
            text=True
        )
        output = result.stdout.strip()
        match = re.search(r'(\d+)x(\d+)', output)
        if match:
            width = int(match.group(1))
            height = int(match.group(2))
            return width, height
        else:
            # 如果无法获取设备分辨率，使用默认值
            print("警告：无法获取设备分辨率，使用默认值1080x1920")
            return 1080, 1920
    except Exception as e:
        print(f"获取设备分辨率时出错: {e}")
        return 1080, 1920

def calculate_swipe_coordinates(width, height, min_swipe_percent, max_swipe_percent, fixed_swipe_percent):
    """计算滑动坐标
    
    从屏幕中间开始，向上滑动屏幕高度的指定百分比
    """
    start_x = width // 2
    start_y = height // 2
    end_x = start_x  # 保持水平位置不变
    
    # 如果指定了固定滑动百分比，使用固定值，否则使用随机范围
    if fixed_swipe_percent is not None:
        swipe_percent = fixed_swipe_percent
        print(f"使用固定滑动高度: 屏幕高度的{swipe_percent:.1f}%")
    else:
        swipe_percent = random.uniform(min_swipe_percent, max_swipe_percent)
        print(f"使用随机滑动高度: 屏幕高度的{swipe_percent:.1f}%")
        
    end_y = start_y - int(height * swipe_percent / 100)  # 向上滑动指定百分比
    
    return start_x, start_y, end_x, end_y

def swipe_up(start_x, start_y, end_x, end_y, duration=100):
    """向上滑动切换到下一个视频"""
    # 从下往上滑动
    subprocess.run([
        ADB_PATH, "shell", "input", "swipe", 
        str(start_x), str(start_y), 
        str(end_x), str(end_y), 
        str(duration)
    ])

def convert_bitrate(bitrate_str):
    """转换码率参数为scrcpy接受的格式
    
    将百分比转换为固定数值 (例如: 50% -> 4M)
    """
    # 如果已经是有效格式 (如 4M, 8000K 等)，直接返回
    if re.match(r'^\d+[KMG]?$', bitrate_str):
        return bitrate_str
    
    # 处理百分比格式
    percent_match = re.match(r'^(\d+)%$', bitrate_str)
    if percent_match:
        percent = int(percent_match.group(1))
        # 假设100%对应8M，按比例转换
        mbps = max(1, int(8 * percent / 100))
        return f"{mbps}M"
    
    # 默认返回中等质量码率
    print(f"警告: 无法解析码率值 '{bitrate_str}'，使用默认值 4M")
    return "4M"

def main():
    current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    
    parser = argparse.ArgumentParser(description=f'使用Scrcpy自动滑动视频 - 版本: 2025-03-20 - 运行时间: {current_time}')
    parser.add_argument('--min-time', type=float, default=25.0, help='滑动之间的最小时间(默认: 25.0秒)')
    parser.add_argument('--max-time', type=float, default=30.0, help='滑动之间的最大时间(默认: 30.0秒)')
    parser.add_argument('--window-size', type=str, default="0.6", help='窗口大小比例(例如: 0.5, 0.6, 1, 1.5, 默认: 0.6)')
    parser.add_argument('--min-swipe-percent', type=float, default=30.0, help='最小滑动高度，屏幕高度的百分比(默认: 30.0)')
    parser.add_argument('--max-swipe-percent', type=float, default=32.0, help='最大滑动高度，屏幕高度的百分比(默认: 32.0)')
    parser.add_argument('--swipe-percent', type=float, help='固定滑动高度，屏幕高度的百分比(覆盖随机范围设置)')
    # 更新参数名称与scrcpy 3.1保持一致
    parser.add_argument('--video-bit-rate', type=str, default="4M", help='视频串流码率设置(例如: 4M, 8M, 默认: 4M)')
    parser.add_argument('--max-fps', type=int, default=30, help='最大帧率设置(默认: 30)')
    parser.add_argument('--no-scrcpy', action='store_true', help='不启动Scrcpy(如果已经运行则使用此选项)')
    parser.add_argument('--custom-swipe', action='store_true', help='使用自定义滑动坐标而不是自动计算')
    parser.add_argument('--start-x', type=int, help='自定义滑动起点X坐标')
    parser.add_argument('--start-y', type=int, help='自定义滑动起点Y坐标')
    parser.add_argument('--end-x', type=int, help='自定义滑动终点X坐标')
    parser.add_argument('--end-y', type=int, help='自定义滑动终点Y坐标')
    parser.add_argument('--video-codec', type=str, choices=['h264', 'h265'], default='h264', help='视频编码器(h264或h265, 默认: h264)')
    parser.add_argument('--audio', action='store_true', help='启用音频转发(Android 11+)')
    parser.add_argument('--video-source', type=str, choices=['display', 'camera'], default='display', help='视频源(display或camera, 默认: display)')
    parser.add_argument('--camera-size', type=str, help='摄像头分辨率(例如: 1920x1080, 仅当--video-source=camera时有效)')
    parser.add_argument('--camera-facing', type=str, choices=['front', 'back'], default='back', help='摄像头方向(front或back, 默认: back)')
    parser.add_argument('--start-app', type=str, help='启动指定应用包名')
    parser.add_argument('--otg', action='store_true', help='使用OTG模式(不需要启用USB调试)')
    parser.add_argument('--gamepad', type=str, choices=['auto', 'uhid'], help='启用游戏手柄支持(auto或uhid)')
    parser.add_argument('--version', action='version', version='Scrcpy自动刷视频脚本 v1.0 (2025-03-20)')
    
    args = parser.parse_args()
    
    # 处理窗口大小参数
    window_size = args.window_size.replace('x', '')  # 移除可能的 'x' 后缀
    
    # 转换码率参数为scrcpy接受的格式
    # 为了保持向后兼容，同时检查--video-bit-rate和--bitrate参数
    bitrate_value = getattr(args, 'video_bit_rate', None)
    if bitrate_value:
        bitrate = convert_bitrate(bitrate_value)
    else:
        print("警告: 使用的是旧版参数--bitrate，建议更新为--video-bit-rate")
        bitrate = convert_bitrate(args.bitrate if hasattr(args, 'bitrate') else "4M")
    
    # 检查执行文件是否存在
    if not os.path.exists(ADB_PATH):
        print(f"错误：找不到ADB执行文件 '{ADB_PATH}'")
        sys.exit(1)
    
    if not args.no_scrcpy and not os.path.exists(SCRCPY_PATH):
        print(f"错误：找不到Scrcpy执行文件 '{SCRCPY_PATH}'")
        sys.exit(1)
    
    # 检查是否有设备连接
    if not check_adb_device():
        print("错误：未检测到ADB设备。请连接您的设备并启用USB调试。")
        sys.exit(1)
    
    # 获取设备分辨率并计算滑动坐标
    width, height = get_device_resolution()
    print(f"设备分辨率: {width}x{height}")
    
    if args.custom_swipe and all([args.start_x, args.start_y, args.end_x, args.end_y]):
        # 使用自定义坐标
        start_x, start_y, end_x, end_y = args.start_x, args.start_y, args.end_x, args.end_y
        print(f"使用自定义滑动坐标: 从 ({start_x},{start_y}) 到 ({end_x},{end_y})")
    else:
        # 自动计算坐标
        start_x, start_y, end_x, end_y = calculate_swipe_coordinates(
            width, height, 
            args.min_swipe_percent, args.max_swipe_percent, 
            args.swipe_percent
        )
        print(f"滑动坐标: 从 ({start_x},{start_y}) 到 ({end_x},{end_y})")
    
    # 获取当前日期和时间
    current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    
    print(f"自动刷视频脚本 - 用户: {os.environ.get('USERNAME', 'zzmzaizai')}")
    print(f"开始时间: {current_time}")
    print(f"将每隔{args.min_time}-{args.max_time}秒随机滑动一次")
    print(f"窗口大小设置: {args.window_size}倍")
    if not args.no_scrcpy:
        print(f"视频码率: {bitrate}")
        # 修复：使用正确的参数名 max_fps 而不是 fps
        print(f"帧率: {args.max_fps}fps")
    print("按Ctrl+C停止。")
    
    scrcpy_process = None
    
    try:
        # 如果需要，在单独的进程中启动Scrcpy
        if not args.no_scrcpy:
            try:
                scale_factor = float(window_size)
                # 基于设备实际宽度计算最大尺寸
                max_size = int(width * scale_factor)
                
                # 准备scrcpy参数 (按scrcpy 3.1格式)
                scrcpy_args = [
                    SCRCPY_PATH
                ]
                
                # 添加基本参数
                if not args.audio:
                    scrcpy_args.append("--no-audio")
                
                # 使用=连接参数名和值，而不是空格分隔
                scrcpy_args.append("--stay-awake")
                scrcpy_args.append(f"--max-size={max_size}")
                scrcpy_args.append(f"--video-bit-rate={bitrate}")
                scrcpy_args.append(f"--max-fps={args.max_fps}")
                scrcpy_args.append(f"--video-codec={args.video_codec}")
                
                # 根据视频源添加参数
                if args.video_source == 'camera':
                    scrcpy_args.append("--video-source=camera")
                    if args.camera_size:
                        scrcpy_args.append(f"--camera-size={args.camera_size}")
                    scrcpy_args.append(f"--camera-facing={args.camera_facing}")
                
                # 添加其他可选参数
                if args.start_app:
                    scrcpy_args.append(f"--start-app={args.start_app}")
                
                if args.otg:
                    scrcpy_args.append("--otg")
                    
                if args.gamepad:
                    scrcpy_args.append(f"--gamepad={args.gamepad}")
                
                print(f"启动Scrcpy, 最大尺寸: {max_size}像素, 视频码率: {bitrate}, 帧率: {args.max_fps}fps, 编码器: {args.video_codec}")
                print(f"命令行: {' '.join(scrcpy_args)}")
                scrcpy_process = subprocess.Popen(scrcpy_args)
                
                # 给Scrcpy一些时间连接
                print("等待Scrcpy连接...")
                time.sleep(5)  # 增加等待时间，确保Scrcpy完全启动
            except ValueError:
                print(f"警告：无法解析窗口大小值 '{window_size}'，使用默认设置启动Scrcpy")
                scrcpy_args = [SCRCPY_PATH, "--no-audio", "--stay-awake", "--video-bit-rate", "4M"]
                scrcpy_process = subprocess.Popen(scrcpy_args)
                time.sleep(5)
        
        # 滑动视频的主循环
        swipe_count = 0
        start_time = time.time()
        while True:
            # 生成指定范围内的随机延迟
            delay = random.uniform(args.min_time, args.max_time)
            print(f"等待{delay:.2f}秒后进行下一次滑动")
            
            # 等待随机延迟
            time.sleep(delay)
            
            # 计算新的滑动坐标（如果使用随机滑动高度）
            if not args.custom_swipe and args.swipe_percent is None:
                # 仅在使用随机范围时重新计算
                start_x, start_y, end_x, end_y = calculate_swipe_coordinates(
                    width, height, 
                    args.min_swipe_percent, args.max_swipe_percent, 
                    None  # 使用随机范围
                )
            
            # 滑动到下一个视频
            swipe_up(start_x, start_y, end_x, end_y)
            swipe_count += 1
            
            # 计算运行时间
            elapsed_time = time.time() - start_time
            hours, remainder = divmod(elapsed_time, 3600)
            minutes, seconds = divmod(remainder, 60)
            
            print(f"已滑动到下一个视频 (总计: {swipe_count}，运行时间: {int(hours)}小时{int(minutes)}分{int(seconds)}秒)")
            
    except KeyboardInterrupt:
        print("\n停止自动化...")
    except Exception as e:
        print(f"发生错误: {e}")
    finally:
        # 确保终止我们启动的Scrcpy进程
        if scrcpy_process:
            scrcpy_process.terminate()
            print("Scrcpy进程已终止。")
        
        # 计算总运行时间
        if 'start_time' in locals():
            elapsed_time = time.time() - start_time
            hours, remainder = divmod(elapsed_time, 3600)
            minutes, seconds = divmod(remainder, 60)
            print(f"总运行时间: {int(hours)}小时{int(minutes)}分{int(seconds)}秒")
        
        # 获取当前日期和时间
        end_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        print(f"结束时间: {end_time}")
        print(f"总共滑动了{swipe_count}个视频")

if __name__ == "__main__":
    main()